package com.vietnam.power.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.vietnam.power.dao.UserDao;
import com.vietnam.power.domain.Country;
import com.vietnam.power.domain.UserInfo;
import com.vietnam.power.domain.UserSearchCriteria;
import com.vietnam.power.persitence.FileUpload;
import com.vietnam.power.persitence.PasswordHistory;
import com.vietnam.power.persitence.UserRole;
import com.vietnam.power.persitence.UserRoleInfo;
import com.vietnam.power.service.FileService;
import com.vietnam.power.service.UserService;
import com.vietnam.power.util.HashCodeGenerator;

@Service
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
public class UserServiceImpl implements UserService {

	@Autowired
	private UserDao userDao;

	@Autowired
	private FileService fileService;

	public void changePassword(UserInfo u) {
		com.vietnam.power.persitence.UserInfo pui = userDao.getUserById(u.getId());

		PasswordHistory passwordHistory = new PasswordHistory();
		passwordHistory.setUserInfo1(pui);
		passwordHistory.setPassword(pui.getPassword());

		List<PasswordHistory> histories = new ArrayList<PasswordHistory>();
		histories.add(passwordHistory);

		pui.setPasswordHistories(histories);
		pui.setPassword(HashCodeGenerator.getHashPassword(u.getPassword()));
		userDao.updateUserInfo(pui);
	}

	public List<Integer> updateInfo(UserInfo u) {
		List<Integer> deletedFileIds = new ArrayList<Integer>();
		com.vietnam.power.persitence.UserInfo pui = userDao.getUserById(u.getId());

		if (u.getAvatarId() != pui.getAvatarId().getId()) {
			deletedFileIds.add(pui.getAvatarId().getId());
			pui.setAvatarId(new FileUpload(u.getAvatarId()));
			fileService.updateFileStatusToActive(u.getAvatarId(), null);
		}

		u.convertToPersist(pui);
		userDao.updateUserInfo(pui);
		return deletedFileIds;
	}

	public UserInfo getUserInfoById(int id) {
		UserInfo u = new UserInfo();
		u.convertToDomain(userDao.getUserById(id));
		return u;
	}

	public List<Country> getListOfCountries() {
		List<Country> lst = new ArrayList<Country>();
		PhoneNumberUtil phoneUtils = PhoneNumberUtil.getInstance();

		for (String s : phoneUtils.getSupportedRegions()) {
			lst.add(new Country(s, new Locale("", s).getDisplayCountry(), "+" + phoneUtils.getCountryCodeForRegion(s)));
		}

		return lst;
	}

	public List<Country> getListOfTimezones() {
		List<Country> lst = new ArrayList<Country>();

		String[] availableTimezones = TimeZone.getAvailableIDs();
		for (String tz : availableTimezones) {
			lst.add(new Country(tz));
		}

		return lst;
	}

	public List<UserInfo> searchUser(UserSearchCriteria criteria) {
		List<UserInfo> userInfos = new ArrayList<UserInfo>();

		for (com.vietnam.power.persitence.UserInfo info : userDao.searchUser(criteria)) {
			UserInfo userInfo = new UserInfo();
			userInfo.convertToDomain(info);
			userInfos.add(userInfo);
		}

		return userInfos;
	}

	public UserInfo getUserByUserName(String username) {
		UserInfo u = new UserInfo();
		u.convertToDomain(userDao.getUserByUserName(username));
		return u;
	}

	public void createInfo(UserInfo u) {
		com.vietnam.power.persitence.UserInfo pui = new com.vietnam.power.persitence.UserInfo();

		pui.setAvatarId(new FileUpload(u.getAvatarId()));
		fileService.updateFileStatusToActive(u.getAvatarId(), null);

		u.convertToPersist(pui);

		// add more for new account
		pui.setEnabled(Boolean.TRUE);
		pui.setAccountNonExpired(Boolean.TRUE);
		pui.setAccountNonLocked(Boolean.TRUE);
		pui.setPassword(HashCodeGenerator.getHashPassword(u.getPassword()));
		pui.setUserName(u.getUserName());
		pui.setPasswordNonExpired(Boolean.TRUE);
		// TODO hard code here for role
		List<UserRole> userRoles = new ArrayList<UserRole>();
		userRoles.add(new UserRole(pui, new UserRoleInfo(1)));
		pui.setUserRoles(userRoles);

		userDao.createUserInfo(pui);
		u.setId(pui.getId());
	}
}
